class AudioVisual {
  constructor({ audioEl = "audio", canvasEl = "canvas" }) {
    this.audioEle = document.querySelector(audioEl);

    this.dataArray = []; //存储音频分析数据

    this.initCanvas(canvasEl);
    this.audioPlay();
    this.draw();
  }
  canvasEle;
  ctx;
  isInit;
  audioAnalyser;

  initCanvas = (el) => {
    this.canvasEle = document.querySelector(el);
    const ctx = this.canvasEle.getContext("2d");
    ctx.width = window.innerWidth * devicePixelRatio;
    ctx.height = (window.innerHeight / 2) * devicePixelRatio;
    this.ctx = ctx;
  };

  audioPlay = () => {
    this.isInit = false;
    this.audioEle.onplay = () => {
      if (this.isInit) {
        return;
      }
      // 初始化
      const audCtx = new AudioContext(); //创建音频上下文
      // 创建音频源节点，就是说获取音频源文件，创建一个节点；
      const source = audCtx.createMediaElementSource(this.audioEle); // 创建音频源节点
      // 然后这个节点文件进行分析
      // 创建分析器节点;分析器 将音频源文件的时序图 用 快速傅里叶变换转换成 频率图
      this.audioAnalyser = audCtx.createAnalyser();
      //   分析数据
      // 值越大 分析越细腻 默认是 2048
      this.audioAnalyser.fftSize = 512;
      // 创建数组接受分析器节点分析的数据
      this.dataArray = new Uint8Array(this.audioAnalyser.frequencyBinCount); //创建一个uint8的数组，并设置长度
      //  将音频节点放入到分析器，叫做连接
      source.connect(this.audioAnalyser);
      // 将分析器节点连接到输出设备
      this.audioAnalyser.connect(audCtx.destination);

      this.isInit = true;
    };
  };

  // 将分析出来的波形绘制到canvas 中
  draw = () => {
    requestAnimationFrame(this.draw);

    // 清空画布
    const { width, height } = this.canvasEle;
    this.ctx.clearRect(0, 0, width, height);
    if (!this.isInit) {
      return;
    }

    // 让分析将其分析的数据存储到 dataArray中
    this.audioAnalyser.getByteFrequencyData(this.dataArray);
    // console.log(this.dataArray);
    this.ctx.fillStyle = "#3cadf9";

    //2.1 取低频的数据
    // const len = this.dataArray.length;
    const len = this.dataArray.length / 2.5;

    //2.2 频率图是对称的，宽度取对半
    // const barWidth = width / len;
    const barWidth = width / len / 2;

    for (let index = 0; index < len; index++) {
      const data = this.dataArray[index];
      const barheight = (data / 255) * height;

      //2.3绘制初始位置在画布中间
      //    const x = index * barWidth;
      const x = index * barWidth + width / 2;
      // 2.4 绘制左边的图的 起始位置
      const x2 = width / 2 - (index + 1) * barWidth;
      const y = height - barheight;

      // 2.5 太密集了，柱子之间六点空隙
      //   this.ctx.fillRect(x, y, barWidth, barheight);
      this.ctx.fillRect(x, y, barWidth - 2, barheight);
      this.ctx.fillRect(x2, y, barWidth - 2, barheight);
    }
  };
}
